#include "gui.h"
#include "gui_switch.h"
#include "gui_box.h"
#include <types.h>
#include <assert.h>
#include <math.h>
#include <stdlib.h>

static void gui_switch_item_event_press(gui_spirit_t *spirit,gui_switch_item_event_arg_t *item_event_arg);
static int gui_switch_create_switch_item(gui_switch_t *switch_obj, gui_switch_type_t type,uint32_t num, int width, int height, int switch_width, int switch_height);

gui_switch_item_event_arg_t item_event_arg[GUI_SWITCH_ITEM_NUM];

/**width: widget width
 * height: widget higth
 * content_width: select windows width
 * content_height: select windows height
 **/
gui_spirit_t *gui_switch_create(gui_switch_type_t type, int width, int height)
{
    gui_switch_t *switch_obj = malloc(sizeof(gui_switch_t));
    if(!switch_obj)
        return;
    switch_obj->width = width;
    switch_obj->height = height;
    switch_obj->switch_type = type;
    switch_obj->padding=1;
    switch_obj->flags=GUI_SWITCH_ITEM_FIXED;
    // calc switch size,switch pos and content pos
    int switch_width, switch_height;
    int switch_x, switch_y;
    int content_width,content_height;
    if (type == GUI_SWITCH_TOP)
    { 
        switch_width = width;
        switch_height = 20;
        content_width=width;
        content_height=height-switch_height;
        switch_x = 0;
        switch_y = 0;
        switch_obj->content_x = 0;
        switch_obj->content_y = switch_height;
    }
    else
    {
        if (type == GUI_SWITCH_BOTTOM)
        {
            switch_width = width;
            switch_height = 20;
            content_width=width;
            content_height=height-switch_height;
            switch_x = 0;
            switch_y = content_height;
            switch_obj->content_x = 0;
            switch_obj->content_y = 0;
        }
        else
        {
            if (type == GUI_SWITCH_LEFT)
            {
                switch_width = 20;
                switch_height = height;
                content_width=width-switch_width;
                content_height=height;
                switch_x = 0;
                switch_y = 0;
                switch_obj->content_x = content_width;
                switch_obj->content_y = 0;
            }
            else
            {
                if (type == GUI_SWITCH_RIGHT)
                {
                    switch_width =20 ;
                    switch_height = height;
                    content_width=width-switch_width;
                    content_height=height;
                    switch_x = content_width;
                    switch_y = 0;
                    switch_obj->content_x = 0;
                    switch_obj->content_y = 0;
                }
            }
        }
    }
    switch_obj->content_width=content_width;
    switch_obj->content_height=content_height;

    // set spirit for switch obj
    gui_spirit_t *spirit = &switch_obj->spirit;
    gui_spirit_init(spirit,0,0,width,height);
    spirit->style.background_color = GUI_RED;
    spirit->type = GUI_SPIRIT_TYPE_SWITCH; // set spirit type
    //create container for spirit
    gui_container_t *container=gui_container_create(spirit);
    if(!container)
        return ;
    spirit->container=container;

    // set spirit for switch item
    gui_spirit_t *switch_spirit = &switch_obj->switch_spirit;
    gui_spirit_init(switch_spirit,switch_x, switch_y, switch_width, switch_height);
    switch_spirit->style.background_color = GUI_BLUE;
    switch_spirit->type=GUI_SPIRIT_TYPE_BOX;
    switch_spirit->style.font_align=GUI_ALIGN_CENTER;
     //create container for spirit
    gui_container_t *switch_container=gui_container_create(switch_spirit);
    if(!switch_container)
        return ;
    switch_spirit->container=switch_container;

    // create bottom surface
    gui_surface_t *surface = spirit->surface;
    surface=gui_surface_create(spirit->width,spirit->height);
    if(!surface)
        return;
    gui_spirit_set_surface(spirit,surface);
    gui_surface_t *switch_surface = switch_spirit->surface;
    switch_surface=gui_surface_create(switch_spirit->width,switch_spirit->height);
    if(!surface)
        return;
    gui_spirit_set_surface(switch_obj,switch_surface);

    if(gui_switch_create_switch_item(switch_obj, type, GUI_SWITCH_ITEM_NUM,width, height, switch_width, switch_height)<0)
    {
        dprintf("[gui_switch] create switch item err\n");
        return NULL;
    }
    // add to container
    gui_container_add(GUI_CONTAINER(spirit), switch_spirit);
 
    return spirit;
}

static int gui_switch_create_switch_item(gui_switch_t *switch_obj, gui_switch_type_t type,uint32_t num, int width, int height, int switch_width, int switch_height)
{
    if(num>GUI_SWITCH_ITEM_NUM)
        num=GUI_SWITCH_ITEM_NUM;
    int item_width = 0;
    int item_height = 0;

    // according type to calculor item size
    switch (type)
    {
    case GUI_SWITCH_LEFT:
    case GUI_SWITCH_RIGHT:
        item_width = switch_width - 2;
        item_height = switch_height / num - 2;
        break;
    case GUI_SWITCH_TOP:
    case GUI_SWITCH_BOTTOM:
        item_width = switch_width / num - 2;
        item_height = switch_height - 2;
      
        break;
    default:
        return -1;
    }

    int i;

    gui_spirit_t *spirit = &switch_obj->spirit;
    gui_spirit_t *switch_spirit = &switch_obj->switch_spirit;

    gui_switch_item_t *switch_item = NULL;
    gui_spirit_t **switch_item_spirit = NULL;
    gui_spirit_t *switch_item_content_spirit = NULL;
    gui_spirit_t *switch_item_icon_spirit = NULL;


    gui_color_t color[]={GUI_WHITE,GUI_RED,GUI_GREEN,GUI_YELLOW};

    for (i = 0; i < num; i++)
    {
        switch_item = &switch_obj->switch_item[i];
        switch_item_spirit=&switch_item->spirit;
        *switch_item_spirit = gui_button_create(); // create item buttton
        gui_button_set_title(*switch_item_spirit,"item");  
        gui_button_set_size_fixed(*switch_item_spirit,1);
        gui_spirit_reset_size(*switch_item_spirit,item_width,item_height);

        //create content container
        switch_item_content_spirit = &switch_item->content_spirit;
        gui_spirit_set_type(switch_item_content_spirit,GUI_SPIRIT_TYPE_BOX);
        gui_spirit_init(switch_item_content_spirit,0, 0, switch_obj->content_width, switch_obj->content_height);
        gui_surface_t *surface=gui_surface_create(switch_item_content_spirit->width,switch_item_content_spirit->height);
        if(!surface)
            continue;
        gui_spirit_set_surface(switch_item_content_spirit,surface);
        switch_item_content_spirit->style.background_color=color[i];
        gui_container_t *container=gui_container_create(switch_item_content_spirit);
        if(!container)
            continue;
        switch_item_content_spirit->container=container;

        //create icon spirit
        switch_item_icon_spirit=&switch_item->icon;
        gui_spirit_init(switch_item_icon_spirit,0, 0, 32, 32);
        surface=gui_surface_create(32,32);
        if(!surface)
            continue;
        gui_spirit_set_surface(switch_item_content_spirit,surface);
            
        // buton event
        item_event_arg[i].item = switch_item;
        item_event_arg[i].switch_obj = switch_obj;
        gui_signal_connect(*switch_item_spirit, "button_press", gui_switch_item_event_press, &item_event_arg[i]);

        // add item content spirit to container
        gui_spirit_set_pos(switch_item_content_spirit, switch_obj->content_x, switch_obj->content_y);
        gui_container_add(GUI_CONTAINER(spirit), switch_item_content_spirit);
    }

    // default item switch
    switch_obj->cur_switch = &switch_obj->switch_item[0];
    //gui_switch_show_cur_switch_item(&switch_obj->cur_switch); // choose current item

    gui_spirit_t *switch_button=NULL;
    // according switch item position
    switch (type)
    {
    case GUI_SWITCH_LEFT:
    {
        int x = 2, y = 2;
        // refresh to switch item surface
        for (i = 0; i < num; i++)
        {
            switch_item = &switch_obj->switch_item[i];
            switch_button = switch_item->spirit;
            switch_item->item_x = x;
            switch_item->item_y = y;
            switch_item->spirit->x = x;
            switch_item->spirit->y = y;
            switch_item->content_spirit.x = switch_obj->content_x;
            switch_item->content_spirit.y = switch_obj->content_y;
            y += switch_item->spirit->height + switch_obj->padding;

            // add to container
            gui_container_add(GUI_CONTAINER(switch_spirit), switch_button);
            //gui_container_add(GUI_CONTAINER(switch_spirit), switch_item_icon_spirit);
        }
    }
    break;
    case GUI_SWITCH_RIGHT:
    {
        int x = 2, y = 2;
        // refresh to switch item surface
        for (i = 0; i < num; i++)
        {

            switch_item = &switch_obj->switch_item[i];
            switch_button = switch_item->spirit;
            switch_item->item_x = x;
            switch_item->item_y = y;
            switch_item->spirit->x = x;
            switch_item->spirit->y = y;
            switch_item->content_spirit.x = switch_obj->content_x;
            switch_item->content_spirit.y = switch_obj->content_y;
            y += switch_item->spirit->height + switch_obj->padding;

            // add to container
            gui_container_add(GUI_CONTAINER(switch_spirit), switch_button);
            //gui_container_add(GUI_CONTAINER(switch_spirit), switch_item_icon_spirit);
        }
    }
    break;
    case GUI_SWITCH_TOP:
    {
        int x = 2, y = 2;
        // refresh to switch item surface
        for (i = 0; i < num; i++)
        {
            switch_item = &switch_obj->switch_item[i];
            switch_button = switch_item->spirit;

            switch_item->item_x = x;
            switch_item->item_y = y;
            switch_item->spirit->x = x ;
            switch_item->spirit->y = y ;
            switch_item->content_spirit.x = switch_obj->content_x;
            switch_item->content_spirit.y = switch_obj->content_y;

            x += switch_item->spirit->width + switch_obj->padding;

            // add to container
            gui_container_add(GUI_CONTAINER(switch_spirit), switch_button);
            //gui_container_add(GUI_CONTAINER(switch_spirit), switch_item_icon_spirit);
        }
    }
    break;
    case GUI_SWITCH_BOTTOM:
    {
        int x = 2, y = 2;
        // refresh to switch item surface
        for (i = 0; i < num; i++)
        {
            switch_item=&switch_obj->switch_item[0];
            switch_button=switch_item->spirit;
            switch_item->item_x = x;
            switch_item->item_y = y;
            switch_item->spirit->x = x ;
            switch_item->spirit->y = y ;
            switch_item->content_spirit.x = switch_obj->content_x;
            switch_item->content_spirit.y = switch_obj->content_y;

            x += switch_item->spirit->width + switch_obj->padding;

            // add to container
            gui_container_add(GUI_CONTAINER(switch_spirit), switch_button);
            //gui_container_add(GUI_CONTAINER(switch_spirit), switch_item_icon_spirit);
        }
    }
    break;
    default:
        break;
    }
    return 0;
}

static void gui_switch_item_event_press(gui_spirit_t *spirit,gui_switch_item_event_arg_t *item_event_arg)
{
    //reapt click switch button,don't work
    gui_spirit_hide(spirit);
    if(item_event_arg->switch_obj->cur_switch==item_event_arg->item)
        return 0;
    gui_spirit_hide(&item_event_arg->switch_obj->cur_switch->content_spirit);
    gui_spirit_show(&item_event_arg->item->content_spirit);
    item_event_arg->switch_obj->cur_switch->spirit->style.background_color = GUI_COLOR_NONE; // change last item color
    item_event_arg->item->spirit->style.background_color = GUI_GREEN;
    gui_spirit_show(item_event_arg->item->spirit);
    item_event_arg->switch_obj->cur_switch=item_event_arg->item;
    return 0;
}


int gui_switch_mouse_press(gui_switch_t *switch_obj,int btn,int x,int y )
{
    gui_spirit_t *switch_spirit=&switch_obj->switch_spirit;
    gui_spirit_t *content_spirit=&switch_obj->cur_switch->content_spirit;

    if(!gui_mouse_btn_down(switch_spirit,btn,x,y))
        return 0;
    if(!gui_mouse_btn_down(content_spirit,btn,x,y))
        return 0;
    
    return -1;
}   

int gui_switch_mouse_motion(gui_switch_t *switch_obj,int x,int y)
{
    gui_spirit_t *switch_spirit=&switch_obj->switch_spirit;
    gui_spirit_t *content_spirit=&switch_obj->cur_switch->content_spirit;
    gui_spirit_t *tmp=NULL;
    
    if(!gui_mouse_motion(switch_spirit,x,y))
        return 0;
    if(!gui_mouse_motion(content_spirit,x,y))
        return 0;
    return -1;
}

int gui_switch_mouse_release(gui_switch_t *switch_obj,int btn,int x,int y)
{
    gui_spirit_t *switch_spirit=&switch_obj->switch_spirit;

    return gui_mouse_btn_up(switch_spirit,btn,x,y);
}

void gui_switch_show_cur_switch_item(gui_switch_t *switch_obj)
{
    gui_spirit_show(switch_obj->cur_switch->spirit);
    gui_spirit_show(&switch_obj->cur_switch->content_spirit);
}


void gui_switch_item_register(gui_switch_item_t *item, gui_spirit_t *spirit)
{
    gui_container_add(GUI_CONTAINER(&item->content_spirit), spirit);
}

void gui_switch_item_unregister(gui_switch_item_t *item, gui_spirit_t *spirit)
{
    gui_container_remove(GUI_CONTAINER(&item->content_spirit), spirit);
}

gui_switch_item_t *gui_switch_item_find(gui_switch_t *switch_obj,uint8_t item_idx)
{
    if(item_idx>GUI_SWITCH_ITEM_NUM-1)
        return NULL;
    return &switch_obj->switch_item[item_idx];
}

void gui_switch_item_show(gui_switch_item_t *item)
{
    gui_spirit_show(&item->content_spirit);
    gui_spirit_show_children(&item->content_spirit);
}

void gui_switch_item_hide(gui_switch_item_t *item)
{
    gui_spirit_hide_all(&item->content_spirit);
}

void gui_switch_get_content_pos(gui_switch_t *switch_obj, int *x, int *y)
{
    if (!x || !y)
        return;
    *x = switch_obj->content_x;
    *y = switch_obj->content_y;
}

void gui_switch_set_pos(gui_switch_t *switch_obj, int x, int y)
{
    if (x < 0 || y < 0)
        return;

    switch_obj->x = x;
    switch_obj->y = y;

    gui_spirit_t *tmp=NULL;
    gui_spirit_t *spirit=&switch_obj->spirit;
    gui_spirit_t *switch_spirit=&switch_obj->switch_spirit;

    list_traversal_all_owner_to_next(tmp,&spirit->container->children_list,list)
    {
        tmp->x+=x;
        tmp->y+=y;
    }
    list_traversal_all_owner_to_next(tmp,&switch_spirit->container->children_list,list)
    {
        tmp->x+=x;
        tmp->y+=y;
    }
    
    spirit->x+=x;
    spirit->y+=y;
}

void gui_switch_get_pos(gui_switch_t *switch_obj, int *x, int *y)
{
    if (!x || !y)
        return;

    *x = switch_obj->x;
    *y = switch_obj->y;
}

void gui_switch_item_set_icon(gui_switch_item_t *item, char *icon)
{
    if (!item || !icon)
        return;
    gui_image_t *img = gui_image_load2(icon, 32, 32);
    uview_bitmap_t bmp;
    uview_bitmap_init(&bmp, 32, 32, img->buff);
    gui_surface_t *surface = item->icon.surface;
    gui_surface_rectfill(surface, 0, 0, bmp.width, bmp.height, bmp.bits);
}

void gui_switch_set_item_disable(gui_switch_t *switch_obj, gui_switch_item_t *item)
{
    gui_button_set_disable(&item->spirit);
}

void gui_switch_set_item_enable(gui_switch_t *switch_obj, gui_switch_item_t *item)
{
    gui_button_set_enable(&item->spirit);
}

void gui_switch_item_set_title(gui_switch_t *switch_obj, gui_switch_item_t *item, char *text, int len)
{
    assert(text);
    if (len > GUI_SWITCH_ITEM_NAME_LEN)
        len = GUI_SWITCH_ITEM_NAME_LEN;
    strncpy(item->name, text, len);
    gui_button_set_title(GUI_BUTTON(item->spirit), text);
}

void gui_switch_show(gui_switch_t *switch_obj)
{
    dprintf("[gui_switch] show switch box %x\n",switch_obj);
    gui_spirit_show(&switch_obj->spirit);
    gui_spirit_show(&switch_obj->switch_spirit);
    gui_spirit_show_children(&switch_obj->switch_spirit);
}
